#include <string.h>
#include "afn04parser.h"

#define callx_Afn04Parser_parseFx(AP,x)\
	call[x] = &AP##Afn04Parser::parseF##x

#define Afn04fx_Afn04Parser_Fx(AP,x)\
AP##Afn04f##x& AP##Afn04Parser::F##x(uint16_t pn)\
{\
	umap[x][pn].F##x.Fn(x);\
	return umap[x][pn].F##x;\
}\

#define int_Afn04Parser_parseFx(AP,x)\
int AP##Afn04Parser::parseF##x(uint8_t* data)\
{\
	AP##Afn04f##x& f = *(AP##Afn04f##x*)data;\
\
	umap[f.Fn()][f.Pn()].F##x = f;\
\
	return f.length();\
}\


#define AFN04_PARSER_IMPLEMENTATION(AP) \
AP##Afn04Parser::AP##Afn04Parser(void)\
{\
	callx_Afn04Parser_parseFx(AP,65);\
	callx_Afn04Parser_parseFx(AP,66);\
	callx_Afn04Parser_parseFx(AP,67);\
	callx_Afn04Parser_parseFx(AP,68);\
}\
void AP##Afn04Parser::clear(void)\
{\
	umap.clear();\
}\
bool AP##Afn04Parser::append(Buffer& b)\
{\
	for(UnionMap::iterator A = umap.begin(); A != umap.end(); A++)\
	{\
		map<uint16_t,Union>::iterator B;\
		for(B = A->second.begin(); B != A->second.end(); B++)\
		{\
			switch(A->first)\
			{\
			case 65: B->second.F65.append(b); break;\
			case 66: B->second.F66.append(b); break;\
			case 67: B->second.F67.append(b); break;\
			case 68: B->second.F68.append(b); break;\
			}\
		}\
	}\
	return umap.size()>0;\
}\
Afn04fx_Afn04Parser_Fx(AP, 65)\
Afn04fx_Afn04Parser_Fx(AP, 66)\
Afn04fx_Afn04Parser_Fx(AP, 67)\
Afn04fx_Afn04Parser_Fx(AP, 68)\
int AP##Afn04Parser::parse(uint8_t *data, int len)\
{\
	int l = len;\
	uint8_t *p = data;\
\
	while(p && l > sizeof(Afn04fbase))\
	{\
		Afn04fbase& b = *(Afn04fbase*)p;\
		Callback func = call[b.Fn()];\
\
		if(func == 0)\
		{\
			return 0;\
		}\
		int r = (this->*func)(p);\
		if(r < sizeof(b))\
		{\
			return 0;\
		}\
		p += r;\
		l -= r;\
	}\
	printf("umap.size(%d)\n", umap.size());\
}\
int_Afn04Parser_parseFx(AP, 65)\
int_Afn04Parser_parseFx(AP, 66)\
int_Afn04Parser_parseFx(AP, 67)\
int_Afn04Parser_parseFx(AP, 68)\

AFN04_PARSER_IMPLEMENTATION(Active)
AFN04_PARSER_IMPLEMENTATION(Pasive)
